<h4>
	<span class="badge bg-info text-dark">Since 15.1.0</span>
</h4>

<p>
	Scrollspy service and set of directives help to watch scroll position changes of the document or a specific container
	and get notified when a part of it is scrolled into or out of the viewport.
</p>

<ngbd-page-header fragment="service" [title]="overview['service']">
	<p>
		The core scrollspy implementation is a
		<a routerLink="../api" fragment="NgbScrollSpyService"><code>NgbScrollSpyService</code></a> that is based on an
		<code>IntersectionObserver</code>. You can see the example of the service working on this very page to highlight
		which documentation section is currently active.
	</p>

	<p>
		You should at least specify which container you'd like to spy on and which sections (fragments) inside this
		container should be watched. Fragments are identified by unique <code>id</code> attributes.
	</p>

	<p>For example, if you want to watch for the document scroll changes, you need to do at least the following:</p>

	<ngbd-code [snippet]="SERVICE"></ngbd-code>

	<p>
		You can also pass multiple <a routerLink="../api" fragment="NgbScrollSpyOptions">options</a> when starting a
		service. For example, you can set a specific container element instead of the whole document, configure the
		intersection observer and change scrolling behavior.
	</p>

	<p>
		You can use the service together with the <code>routerLink</code> directive and its <code>[fragment]</code> input,
		or you can force the scrollspy to get to a specific fragment via the <code>.scrollTo()</code> method.
	</p>
</ngbd-page-header>

<ngbd-page-header fragment="directive" [title]="overview['directive']">
	<p>
		The directive will help you to setup the scrollspy service instance on a specific container. It is merely a
		syntactic sugar around the service that will start and add fragments automatically, as well as clean everything up
		when host component is destroyed.
	</p>

	<p>It will look something like this:</p>

	<ngbd-code [snippet]="DIRECTIVE"></ngbd-code>

	<p>
		Please see and the <a routerLink="../examples">demos</a> and
		<a routerLink="../api" fragment="NgbScrollSpy"><code>NgbScrollSpy</code> API</a> for all available inputs and
		outputs.
	</p>
</ngbd-page-header>

<ngbd-page-header fragment="highlighting" [title]="overview['highlighting']">
	<p>
		There are also two helper directives: <code>NgbScrollSpyMenu</code> and <code>NgbScrollSpyItem</code>. They will
		highlight the active item in a menu, nav or any custom list.
	</p>

	<h4>Individual items</h4>

	<p>
		<a routerLink="../api" fragment="NgbScrollSpyItem"><code>NgbScrollSpyItem</code></a> directive either gets the
		nearest scrollspy from the DI or uses the direct reference. It adds and removes <code>.active</code> class
		dynamically based on the current scrollspy state.
	</p>

	<ngbd-code [snippet]="ITEM_BASIC"></ngbd-code>

	<p>It has also several convenient ways of referencing related scrollspies and fragments:</p>

	<ngbd-code [snippet]="ITEM_SYNTAX"></ngbd-code>

	<p>For more details, please see the <a routerLink="../examples" fragment="items">related remo</a></p>

	<h4>Hierarchical menus</h4>

	<p>
		In case of multiple nesting levels, you might want to highlight the whole branch of the menu and not only a single
		item. For this purpose, you can use the
		<a routerLink="../api" fragment="NgbScrollSpyMenu"><code>NgbScrollSpyMenu</code></a> directive on a container with
		items.
	</p>

	<ngbd-code [snippet]="MENU"></ngbd-code>

	<p>
		It this case you might reference scrollspy only once at the menu level, or not reference at all if it is available
		via DI.
	</p>

	<p>For more details, please see the <a routerLink="../examples" fragment="nested">related remo</a></p>
</ngbd-page-header>

<ngbd-page-header fragment="customization" [title]="overview['customization']">
	<p>
		If you want to customize the <code>IntersectionObserver</code> you can pass <code>rootMargin</code> and
		<code>threshold</code> options when starting the service.
	</p>

	<p>
		If you don't like the default scrollspy behavior or would like to process intersection observer events on your own,
		you can completely override the algorithm by providing your own implementation function via the
		<code>[processChanges]="myCustomProcess"</code> input or set it directly via the service start options.
	</p>

	<p>
		For example, default scrollspy implementation doesn't allow for gaps in-between items, ex. if you're in-between
		fragments 'one' and 'two' ('one' is not visible anymore and 'two' is not visible yet), we'll still mark item 'one'
		as active.
	</p>

	<p>
		If you provide your own function, you'll get the list of the intersection observer entries and you can process them
		as you wish. You can use the current scrollspy state and it's up to you to call the provided
		<code>changeActive()</code> method when it's time to change the active fragment. You can also use the
		<code>context</code> that is persisted across the calls.
	</p>

	<ngbd-code [snippet]="CUSTOMIZATION"></ngbd-code>
</ngbd-page-header>
